package nicg.st.service.ahp;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author GeChen
 * @Description
 * @date 2019/11/3 23:04
 */
public class MatrixCreater {
    public class Pos {
        public int Row;
        public int Line;
    }

    private int Rows, Lines;//待扰动矩阵的行和列
    private List<Pos> Mpos;//原矩阵中待扰动的m个位置
    private int M;
    private int N;//生成矩阵的个数
    private double[][] RawMatrix;//待扰动的原矩阵
    private int Optimistic = 0;//进行正扰动还是负扰动
    private List<double[][]> allMatrix;

    public List<double[][]> AllMatrix() {
        CreaterInitial();
        if (allMatrix.size() > 0) {
            return allMatrix;
        } else
            return null;
    }

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="rawmatrix">原始矩阵</param>
    /// <param name="r">原始矩阵的行数</param>
    /// <param name="l">原始矩阵的列数</param>
    /// <param name="n">生成矩阵的个数</param>
    public MatrixCreater(double[][] rawmatrix, int r, int l, int n, int m) {
        allMatrix = new ArrayList<double[][]>();
        Rows = r;
        Lines = l;
        N = n;
        if (m <= r * l)
            M = m;
        else
            M = 0;
        RawMatrix = new double[Rows][Lines];
        //MatrixCreater.CopyMatrix(rawmatrix, ref RawMatrix, Rows, Lines);
        RawMatrix = CopyMatrix(rawmatrix, Rows, Lines);
        Mpos = new ArrayList<Pos>();
    }

    /// <summary>
    /// 随机生成m个要扰动的位置
    /// </summary>
    /// <param name="rs">原矩阵行数</param>
    /// <param name="lis">原矩阵列数</param>
    private void CreatePosition(int rs, int lis) {
        Mpos.clear();
        Random Ran = new Random();
        int count = M;
        while (count > 0) {
            Pos ps = new Pos();
            ps.Row = Ran.nextInt(rs);
            ps.Line = Ran.nextInt(lis);
            Mpos.add(ps);
            count--;
        }
    }

    /// <summary>
    /// 复制矩阵数据
    /// </summary>
    /// <param name="Source">源矩阵</param>
    /// <param name="Destination">目标矩阵</param>
    /// <param name="rows">行数</param>
    /// <param name="lines">列数</param>
    public static double[][] CopyMatrix(double[][] Source, int rows, int lines) {
        double[][] Destination = new double[rows][lines];
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < lines; j++) {
                Destination[i][j] = Source[i][j];
            }
        }
        return Destination;
    }

    /// <summary>
    /// 生成并保存这n个矩阵
    /// </summary>
    private void CreaterInitial() {
        allMatrix.clear();
        int count = N;
        Random Ran = new Random();
        while (count > 0) {

            double[][] Des = new double[Rows][Lines];
            //MatrixCreater.CopyMatrix(RawMatrix, ref Des, Rows, Lines);
            Des = CopyMatrix(RawMatrix, Rows, Lines);
            Optimistic = Ran.nextInt(2);
            Pos ps;
            int i = 0;
            double tmp = 0;
            if (Optimistic == 0) {
                CreatePosition(Rows, Lines);
                for (i = 0; i < Mpos.size(); i++) {
                    ps = Mpos.get(i);
                    tmp = Ran.nextDouble() / 10;
                    Des[ps.Row][ps.Line] -= tmp;
                    Des[ps.Line][ps.Row] = 1 / Des[ps.Row][ps.Line];
                }
            } else {
                CreatePosition(Rows, Lines);
                for (i = 0; i < Mpos.size(); i++) {
                    ps = Mpos.get(i);
                    tmp = Ran.nextDouble() / 10;
                    Des[ps.Row][ps.Line] += tmp;
                    Des[ps.Line][ps.Row] = 1 / Des[ps.Row][ps.Line];
                }
            }
            for (i = 0; i < Rows; i++) {
                Des[i][i] = 1;
            }
            allMatrix.add(Des);
            count--;
        }
    }
}